package main

import (
	"gomicrov4-sharemod/gateway-api/middlewares"
	"gomicrov4-sharemod/gateway-api/routers"
	"gomicrov4-sharemod/gateway-api/utils"
	"html/template"
	"net/http"
	"time"

	sentinelPlugin "github.com/alibaba/sentinel-golang/pkg/adapters/gin"
	"github.com/gin-contrib/cors"
	"github.com/gin-contrib/sessions"
	"github.com/gin-contrib/sessions/cookie"
	"github.com/gin-gonic/gin"
)

// 编译windows版: go build -o gateway-api.exe main.go
// 编译linux版: go build -o gateway-api main.go
func main() {
	// 初始化 Zap logger
	utils.InitLogger()

	// 设置运行模式
	gin.SetMode(utils.AppMode)

	r := gin.Default()

	//定义模板函数
	r.SetFuncMap(template.FuncMap{
		"UninxToDate":           utils.UnixToDate,
		"CutTime":               utils.CutTime,
		"HandleTwoDecimalPoint": utils.HandleTwoDecimalPoint,
		"StringSplit":           utils.StringSplit,
		"StrToHtml":             utils.StrToHtml,
	})

	// ------------------- 第三方跨域中间件开始 -------------------
	//加载中间件
	// r.Use(middlewares.CsrfMiddleware) //自定义跨域中间件

	// 默认配置
	// r.Use(cors.Default())
	r.Use(cors.New(cors.Config{
		AllowMethods:     []string{"GET", "POST", "PUT", "PATCH", "DELETE", "HEAD", "OPTIONS"},
		AllowHeaders:     []string{"Origin", "Content-Length", "Content-Type", "Authorization", "Token", "session"},
		AllowAllOrigins:  true,
		AllowCredentials: false,
		MaxAge:           12 * time.Hour,
	}))

	// 使用自定义 Recovery 中间件（替换默认的 gin.Recovery）
	r.Use(middlewares.RecoveryMiddleware())

	// 解析请求参数中间件
	r.Use(middlewares.ParseArgsMiddleware)

	// http调用限流方式
	r.Use(sentinelPlugin.SentinelMiddleware(
		sentinelPlugin.WithResourceExtractor(func(ctx *gin.Context) string {
			return utils.LimiterResource
		}),
		sentinelPlugin.WithBlockFallback(func(ctx *gin.Context) {
			// 返回给前端，超过了qps
			ctx.AbortWithStatusJSON(400, map[string]interface{}{
				"code":    400,
				"data":    nil,
				"message": "人气太火爆了，请稍等",
			})
		}),
	))

	// 使用 Zap 日志中间件
	r.Use(middlewares.ZapLogger())
	// ------------------- 第三方跨域中间件结束 -------------------

	// ----------------------- 处理错误开始 -----------------------
	// 自定义404处理
	r.NoRoute(func(c *gin.Context) {
		c.JSON(http.StatusNotFound, gin.H{
			"code":    http.StatusNotFound,
			"data":    nil,
			"message": "Not Found API",
		})
	})
	// ----------------------- 处理错误结束 -----------------------

	// ------------------ cookie && session 开始 -----------------
	//配置cookie && session
	store := cookie.NewStore([]byte("secret"))
	store.Options(sessions.Options{
		MaxAge:   7200,
		Path:     "/",
		HttpOnly: true,
	})

	//基于redis 存储session
	// store, err := redis.NewStore(10, "tcp", "localhost:6379", "", []byte("secret"))
	// if err != nil {
	// 	fmt.Println("store", err.Error())
	// 	return
	// }
	r.Use(sessions.Sessions("gin_sesstion", store))
	// ------------------ cookie && session 结束 -----------------

	//定义访问静态资源
	r.Static("/static", "./static")

	//访问目录
	r.StaticFile("/favicon.ico", "./static/favicon.ico")
	r.StaticFile("/downloads", "./downloads")

	//加载路由配置
	routers.ApiRouters(r)

	//运行服务
	r.Run(utils.AppHost + ":" + utils.AppPort)
}
